//
//  MKUIElementSelectOptionViewController.m
//  MKUI
//
//  Created by 苏尚进 on 2023/7/12.
//  Copyright © 2023 moon. All rights reserved.
//

#import "MKUIElementSelectOptionViewController.h"
#import "MKUIPreCompile.h"
#import "NSArray+MKUI.h"

@implementation MKUIElementSelectOption
- (NSString *)description{
    return [NSString stringWithFormat:@"<%@:%p,value:%@,text:%@>",NSStringFromClass(self.class),self,self.value,self.text];
}
+ (MKUIElementSelectOption *)optionWithValue:(nullable id)value{
    return [self optionWithValue:value text:[value description]];
}
+ (MKUIElementSelectOption *)optionWithValue:(nullable id)value text:(nullable NSString *)text{
    MKUIElementSelectOption *option = [[MKUIElementSelectOption alloc] init];
    option.value = value;
    option.text = text;
    return option;
}
+ (NSArray<MKUIElementSelectOption *> *)optionsWithTexts:(NSArray<NSString *> *)texts{
    return [self optionsWithTexts:texts values:texts];
}
+ (NSArray<MKUIElementSelectOption *> *)optionsWithTexts:(NSArray<NSString *> *)texts values:(NSArray *)values{
    NSMutableArray<MKUIElementSelectOption *> *options = [[NSMutableArray alloc] init];
    for(int i=0;i<texts.count;i++){
        MKUIElementSelectOption *option = [MKUIElementSelectOption optionWithValue:values[i] text:texts[i]];
        [options addObject:option];
    }
    return options;
}
+ (NSArray<MKUIElementSelectOption *> *)optionsWithValues:(NSArray *)values textBlock:(NSString *(^)(id value))textBlock{
    NSMutableArray<MKUIElementSelectOption *> *options = [[NSMutableArray alloc] init];
    for(int i=0;i<values.count;i++){
        id value = values[i];
        NSString *text = textBlock?textBlock(value):[value description];
        MKUIElementSelectOption *option = [MKUIElementSelectOption optionWithValue:value text:text];
        [options addObject:option];
    }
    return options;
}
@end
@implementation MKUIElementSelectOptionTableViewCell
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{
    if(self=[super initWithStyle:style reuseIdentifier:reuseIdentifier]){
        self.selectionStyle = UITableViewCellSelectionStyleNone;
    }
    return self;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated{
    [super setSelected:selected animated:animated];
    self.accessoryType = selected?UITableViewCellAccessoryCheckmark:UITableViewCellAccessoryNone;
}
- (void)customReloadCellModel{
    [super customReloadCellModel];
    MKUIElementSelectOption *modelValue = self.cellModel.modelValue;
    self.elementView.titleText = modelValue.text.length>0?modelValue.text:modelValue.value;
    self.accessoryType = self.cellModel.selected?UITableViewCellAccessoryCheckmark:UITableViewCellAccessoryNone;
}
@end

@interface MKUIElementSelectOptionViewController (){
    NSMutableArray *_selectedOptions;
    BOOL _NeedReloadData;
}
@property(nonatomic,strong) MKUITableView *tableView;
@property(nonatomic,strong) UIButton *doneButton;
@property(nonatomic,assign) UITableViewStyle style;
@end

@implementation MKUIElementSelectOptionViewController
- (id)initWithStyle:(UITableViewStyle)style{
    if(self=[super init]){
        _selectedOptions = [[NSMutableArray alloc] init];
        self.optionCellClass = MKUIElementSelectOptionTableViewCell.class;
        self.style = style;
    }
    return self;
}
- (id)init{
    UITableViewStyle style = UITableViewStylePlain;
    if (@available(iOS 13.0, *)) {
        style = UITableViewStyleInsetGrouped;
    } else {
        style = UITableViewStyleGrouped;
    }
    return [self initWithStyle:style];
}
#ifdef DEBUG
- (void)dealloc{
    
}
#endif
- (void)viewDidLoad {
    [super viewDidLoad];
    if(_doneButtonText.length==0){
        _doneButtonText = @"Done";
    }
    self.tableView = [[MKUITableView alloc] initWithFrame:self.view.bounds style:(self.style)];
    self.tableView.tableHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 1, 20)];
    [self.view addSubview:self.tableView];
    _NeedReloadData = YES;
    //
    self.doneButton = [[UIButton alloc] init];
    [self.doneButton setTitle:self.doneButtonText forState:(UIControlStateNormal)];
    [self.doneButton setTitleColor:[UIColor systemBlueColor] forState:(UIControlStateNormal)];
    self.doneButton.titleLabel.font = [UIFont systemFontOfSize:18];
    [self.doneButton addTarget:self action:@selector(__onDoneButtonTap:) forControlEvents:UIControlEventTouchUpInside];
    [self.doneButton sizeToFit];
    UIBarButtonItem *doneItem = [[UIBarButtonItem alloc] initWithCustomView:self.doneButton];
    self.navigationItem.rightBarButtonItem = doneItem;
}
- (void)__onDoneButtonTap:(id)sender{
    if(self.whenDone){
        self.whenDone(self);
    }
}
- (void)viewWillLayoutSubviews{
    [super viewWillLayoutSubviews];
    CGRect bounds = self.view.bounds;
    self.tableView.frame = bounds;
    if(_NeedReloadData){
        _NeedReloadData = NO;
        [self reloadData];
    }
}
- (void)setOptions:(NSArray<MKUIElementSelectOption *> *)options{
    _options = options;
    [self setNeedReloadData];
}
- (void)setSelectedOption:(MKUIElementSelectOption *)selectedOption{
    self.selectedOptions = selectedOption?@[selectedOption]:nil;
}
- (MKUIElementSelectOption *)selectedOption{
    return _selectedOptions.firstObject;
}
- (void)setSelectedOptions:(NSArray<MKUIElementSelectOption *> *)selectedOptions{
    [_selectedOptions removeAllObjects];
    if(selectedOptions.count){
        [_selectedOptions addObjectsFromArray:selectedOptions];
    }
    [self setNeedReloadData];
}
- (id)selectedValue{
    return self.selectedOption.value;
}
- (void)setSelectedValue:(id)selectedValue{
    for(MKUIElementSelectOption *option in self.options){
        BOOL eq = [selectedValue conformsToProtocol:@protocol(NSObject)]?option.value==selectedValue||[selectedValue isEqual:option.value]:option.value==selectedValue;
        if(eq){
            self.selectedOption = option;
            return;
        }
    }
}
- (NSArray<MKUIElementSelectOption *> *)selectedOptions{
    if(_selectedOptions.count==0) return nil;
    return [self.options mk_map:^id _Nullable(MKUIElementSelectOption *obj) {
        if([_selectedOptions containsObject:obj]) return obj;
        return nil;
    }];
}
- (void)setAllowsMultipleSelection:(BOOL)allowsMultipleSelection{
    _allowsMultipleSelection = allowsMultipleSelection;
    self.tableView.model.allowsMultipleSelection = allowsMultipleSelection;
    self.tableView.allowsMultipleSelection = allowsMultipleSelection;
    [self setNeedReloadData];
}
- (NSArray *)selectedValues{
    return [self.selectedOptions mk_map:^id _Nullable(MKUIElementSelectOption *obj) {
        return obj.value;
    }];
}
- (void)setSelectedValues:(NSArray *)selectedValues{
    NSMutableArray *selectedOptions = [[NSMutableArray alloc] init];
    for(MKUIElementSelectOption *option in self.options){
        for(id selectedValue in selectedValues){
            BOOL eq = [selectedValue conformsToProtocol:@protocol(NSObject)]?option.value==selectedValue||[selectedValue isEqual:option.value]:option.value==selectedValue;
            if(eq){
                [selectedOptions addObject:option];
                break;
            }
        }
    }
    self.selectedOptions = selectedOptions;
}
- (void)setNeedReloadData{
    _NeedReloadData = YES;
    [self.view setNeedsLayout];
}
- (void)reloadData{
    MKUITableViewModel *model = self.tableView.model;
    model.allowsMultipleSelection = self.allowsMultipleSelection;
    self.tableView.allowsMultipleSelection = self.allowsMultipleSelection;
    
    [model removeAllSectionModels];
    @MK_WEAKIFY(self);
    Class cellClass = self.optionCellClass?self.optionCellClass:MKUIElementSelectOptionTableViewCell.class;
    for(MKUIElementSelectOption *option in self.options){
        MKUIElementTableViewCellModelDetail *cm = [MKUIElementTableViewCellModelDetail modelWithValue:option cellClass:cellClass whenClick:^(MKUITableViewCellModel *cm) {
            @MK_NORMALIZE(self);
            if(self.allowsMultipleSelection){
                BOOL selected = cm.selected;
                if(selected){
                    [self->_selectedOptions addObject:option];
                }else{
                    [self->_selectedOptions removeObject:option];
                }
                [cm setSelected:selected animated:YES];
            }else{
                self.selectedOption = option;
                [cm setSelected:YES animated:YES];
            }
            if(self.whenChange){
                self.whenChange(self);
            }
        }];
        cm.selected = [self.selectedOptions containsObject:option];
        [model addCellModel:cm];
    }
    [model reloadTableViewData];
}
@end
